using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;

namespace ThomasCarpe.Diagnostics.Logging {

	/// <summary>
	/// Acts as a bridge between EventLogExtended and the standardized LoggingBase API.
	/// Performs basic functions of writing entries to the event log.
	/// </summary>
	public class LoggingEvent : LoggingBase {

		public LoggingEvent(string name) : base(name) { }
		public LoggingEvent(string name, LogDetailLevel infoLevel) : base(name, infoLevel) { }

		private EventLogExtended eventLog;

		public override bool CanOpen {
			get { return false; }
		}

		/// <summary>
		/// Writes an entry to the event log.
		/// </summary>
		/// <param name="infoLevel"></param>
		/// <param name="text"></param>
		public override void Write(LogDetailLevel infoLevel, string text) {
			if (this.IsLevelThresholdReached(infoLevel)) {
				// TODO implement impersonation or assertion here if necessary
				EventLogEntryType type = ConvertToEventLogEntryType(infoLevel);
				eventLog.WriteEntry(text, type);
			}
		}

		public override void Write(LogDetailLevel infoLevel, string text, string category) {
			Write(infoLevel, category + ": " + text);
		}

		public override void Write(LogItem info) {
			string text = info.Text;
			if (info.RelatedException != null)
				text += " " + info.RelatedException.Message;
			Write(info.Level, text, info.Category);
		}

		public void Write(LogDetailLevel infoLevel, string text, int eventId, short category, byte[] data) {
			if (this.IsLevelThresholdReached(infoLevel)) {
				// TODO implement impersonation or assertion here if necessary
				EventLogEntryType type = ConvertToEventLogEntryType(infoLevel);
				eventLog.WriteEntrySimple(text, type, eventId, category, data);
			}
		}

		/// <summary>
		/// Create an EventLog instance and assign its source.
		/// </summary>
		public override void Initialize() {
			eventLog = new EventLogExtended();
			eventLog.Source = this.Name;
			// TODO consider also setting up the Log property.
		}

		private static EventLogEntryType ConvertToEventLogEntryType(LogDetailLevel level) {
			switch (level) {
				case LogDetailLevel.None:
				case LogDetailLevel.Debug:
				case LogDetailLevel.Info:
					return EventLogEntryType.Information;
				case LogDetailLevel.Warning:
					return EventLogEntryType.Warning;
				case LogDetailLevel.Error:
				case LogDetailLevel.CriticalError:
					return EventLogEntryType.Error;
				default:
					throw new ArgumentOutOfRangeException("Unknown type: " + level.ToString());
			}
		}

		public override void Open() {
			throw new NotImplementedException("The method is not implemented.");
		}
		public override void Close() {
			throw new NotImplementedException("The method is not implemented.");
		}

		// TODO implement the more specific hard-coded event class implemnentation also, if possible

	} // class

} // namespace
